import java.util.*;
import java.util.concurrent.*;

public class FixedThreadPoolTest
{
	public static void main(String [] args) throws Exception
	{
		ExecutorService threadPoolExec = Executors.newFixedThreadPool(4); // Mine is quad-core, by the way.
		
		long timeIn = System.currentTimeMillis();
		
		threadPoolExec.submit(new FactorialCalc(20));
		threadPoolExec.submit(new FactorialCalc(19));
		threadPoolExec.submit(new FactorialCalc(18));
		threadPoolExec.submit(new FactorialCalc(17));
		
		threadPoolExec.submit(new FactorialCalc(20));
		threadPoolExec.submit(new FactorialCalc(19));
		threadPoolExec.submit(new FactorialCalc(18));
		threadPoolExec.submit(new FactorialCalc(17));
				
		threadPoolExec.shutdown();
		threadPoolExec.awaitTermination(1000, TimeUnit.SECONDS);
		long timeOut = System.currentTimeMillis();
		double elapsedTime = (timeOut - timeIn);
		
		System.out.println(elapsedTime);
	}
	
	private static class FactorialCalc implements Runnable
	{
		private long numToProcess = 1;
		public FactorialCalc(long numIn)
		{
			numToProcess = numIn;
		}
		public void run()
		{
			// Simulates the CPU intensive task, just for demo.
			// Watch out for compiler optimization here.
			long res = 1;
			for(int i = 1; i < 10000000; i++)
			{
				res = calculate(numToProcess);
				res = res % i;
			}
			System.out.println(calculate(numToProcess));			
		}
		
		private long calculate(long in)
		{
			if(in < 2) // Itz ok for demo code; ignore the negative number cases and huge number cases.
			{
				return 1;
			}
			else
				return in * calculate(in - 1);
		}
	}
}